#include<iostream>
#include<pthread.h>
#include<functional>
#
using namespace std;

template<class T>
using func_t = funtion<void(T)>;

template<class T>
class Thread
{
public:
    Thread(pthread_t tid, string& threadname, T data, func_t<T> f)
            :_tid(tid)
            ,_threadname(threadname)
            ,_data(data)
            ,_f(f)
    {}

    static void* ThreadRoutine(void* args)
    {
        Thread* ts = static_cast<Thread*> args;
        ts->_f(ts->data);

        return nullptr;
    }

    bool start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, (void*)_data);
        if(n == 0)
        {
            _isrunning = true;
            return true;
        }
        else retuen false;
    }

    bool join()
    {
        if(!_isrunning) return true;

        int n = pthread_join();
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        else return false;
    }

    string Threadname()
    {
        return _threadname;
    }

    bool isrunning()
    {
        return _isrunning;
    }

    ~Thread()
    {}

public:
    pthread_t _tid;
    string _threadname;
    bool _isrunning;
    T _data;
    func_t<T> _f;
};